//
// Created by Ge on 2024/3/6.
//
#include "include/AssimpHelper.h"
#include "jni.h"
#include "assimp/postprocess.h"
#include "assimp/scene.h"
#include "assimp/Exporter.hpp"
#include "assimp/Importer.hpp"
#include "LogUts.h"


#ifndef ASSIMP_HELPER_REGISTER_CLASS
#define ASSIMP_HELPER_REGISTER_CLASS "com/ziya/android/a3dmodel/nativelib/AssimpHelper"
#endif

JNINativeMethod methods[] = {
        {"exportModel", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",   (void *) &exportModel},
        {"init",        "()V",   (void *) &init},
        {"destroy", "()V", (void *) &destroy},
};

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env;
    if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
        return -1;
    }
    jclass clz = env->FindClass(ASSIMP_HELPER_REGISTER_CLASS);
    env->RegisterNatives(clz, methods, sizeof(methods) / sizeof(JNINativeMethod));
    env->DeleteLocalRef(clz);
    return JNI_VERSION_1_6;
}

JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
    JNIEnv *env = NULL;
    if (JNI_OK != vm->GetEnv((void **) &env, JNI_VERSION_1_6)) {
        return;
    }
    jclass clz = env->FindClass(ASSIMP_HELPER_REGISTER_CLASS);
    env->UnregisterNatives(clz);
    env->DeleteLocalRef(clz);
}

Assimp::Importer importer;
Assimp::Exporter exporter;

void init(JNIEnv *env, jobject thiz) {

}

void destroy(JNIEnv *env, jobject thiz) {

}


jint exportModel(JNIEnv *env, jobject thiz, jstring model_path,
                 jstring export_path, jstring formatId) {
    const char *modePath = env->GetStringUTFChars(model_path, nullptr);
    const aiScene *scene = importer.ReadFile(modePath, aiProcess_Triangulate
                                                       /*| aiProcess_FlipUVs*/
                                                       | aiProcess_PreTransformVertices
            /*| aiProcess_EmbedTextures*/);
    if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
        LOGE("模型加载失败");
        env->ReleaseStringUTFChars(model_path, modePath);
        return 1;
    }
    LOGD("模型加载成功");
    const char *exportPath = env->GetStringUTFChars(export_path, nullptr);
    const char *pFormatId = env->GetStringUTFChars(formatId, nullptr);
    const aiReturn aiResult = exporter.Export(scene, pFormatId, exportPath,
                                              aiProcess_JoinIdenticalVertices);
    if (aiResult != aiReturn_SUCCESS) {
        LOGE("模型导出失败");
        env->ReleaseStringUTFChars(export_path, exportPath);
        env->ReleaseStringUTFChars(formatId, pFormatId);
        return 1;
    }
    LOGD("模型导出成功");
    /**
     * 释放字符串资源
     */
    env->ReleaseStringUTFChars(model_path, modePath);
    env->ReleaseStringUTFChars(export_path, exportPath);
    env->ReleaseStringUTFChars(formatId, pFormatId);
    return 0;
}
